package com.ymx.darling.spring.mapper;

import com.ymx.darling.build.DarlingConfig;
import com.ymx.darling.exception.DarlingException;
import com.ymx.darling.log.Log;
import com.ymx.darling.session.SessionFactory;
import com.ymx.darling.session.defaults.DefaultSessionFactory;
import com.ymx.darling.spring.transaction.SpringTransactionManager;
import org.springframework.beans.factory.FactoryBean;

import javax.sql.DataSource;

/**
 * @author 爱Java的小于
 */
public class SessionFactoryBean implements FactoryBean<SessionFactory> {
    /**
     * 数据源
     */
    private DataSource dataSource;
    /**
     * SessionFactory实例 程序运行期间保持单例模式
     */
    private SessionFactory sessionFactory;
    /**
     *  日志打印状态
     */
    private Class<? extends Log> logImpl;
    /**
     * 缓存开启状态
     */
    private boolean cacheEnabled;
    /**
     * 实体所在的包
     */
    private String entityPackage;
    /**
     * mapper的xml文件的类路径
     */
    private String mapperLocation;

    /**
     * 根据该类中属性信息构建SessionFactory实例
     * @return 此方法会被延迟到spring调用getObject时执行
     */
    protected SessionFactory builderMapperFactory() {
        return new DefaultSessionFactory(builderConfiguration());
    }

    /**
     * 根据属性信息构建Configuration实例
     * @return Configuration
     */
    private DarlingConfig builderConfiguration(){
        if (dataSource == null) {
            throw new DarlingException("配置SessionFactoryBean时没有指定'datasource属性值'");
        }
        DarlingConfig darlingConfigInfo = new DarlingConfig();
        // 配置日志打印状态
        darlingConfigInfo.setLogImplClass(this.logImpl);
        // 配置缓存开启状态
        darlingConfigInfo.cacheEnabled(this.cacheEnabled);
        // 配置实体类包
        darlingConfigInfo.setEntityPackage(this.entityPackage);
        // 配置xml的文件路径
        darlingConfigInfo.setMapperLocations(this.mapperLocation);
        // 配置mapper包扫描器 类型处理器
        // mapper包名从@darlingMapperScanner中获取
        String mapperPackage = MapperScannerConfigurer.getMapperPackage();
        darlingConfigInfo.setMapperPackage(mapperPackage);
        // 配置事务管理器
        SpringTransactionManager transactionManager = new SpringTransactionManager(this.dataSource);
        darlingConfigInfo.setTransactionManager(transactionManager);
        // 返回自动配置后的数据
        return darlingConfigInfo;
    }


    @Override
    public SessionFactory getObject() {
        if (this.sessionFactory == null)
            this.sessionFactory = builderMapperFactory();
        return this.sessionFactory;
    }

    @Override
    public Class<?> getObjectType() {
        return SessionFactory.class;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setLogImpl(Class<? extends Log> logImpl) {
        this.logImpl = logImpl;
    }

    public void setMapperLocation(String mapperLocation) {
        this.mapperLocation = mapperLocation;
    }

    public void setEntityPackage(String entityPackage) {
        this.entityPackage = entityPackage;
    }

    public void setCacheEnabled(boolean cacheEnabled) {
        this.cacheEnabled = cacheEnabled;
    }
}
